datepicker = {
    pickers: [],
    currentPick : null,
    create: function (query, options) {
        var referers = document.querySelectorAll(query);
        var options = extend({}, datepicker.defaults, options);
        for (var i = 0; i < referers.length; i++) {
            this.pickers.push(new DatePick(referers[i], options));
        }
        document.removeEventListener('click', this.handleClick, false);
        document.addEventListener('click', this.handleClick, false);

    },
    handleClick: function (event) {
        var target = event.target;
        var alt = false;
        if (datepicker.currentPick) {
            if (target.className == 'month-navigate next') {
                datepicker.currentPick.getNextMonth();
            } else if (target.className == 'month-navigate previous') {
                datepicker.currentPick.getPreviousMonth();
            } else if (target.className == 'year-navigate next') {
                datepicker.currentPick.getNextYear();
            } else if (target.className == 'year-navigate previous') {
                datepicker.currentPick.getPreviousYear();
            } else if (target.className == 'day' || target.className == 'day selected') {
                datepicker.currentPick.setDate(target.innerHTML);
                datepicker.currentPick.hide();
                datepicker.currentPick = null;
            } else
                alt = true;
        }
        if (!datepicker.currentPick || alt) {
            for (let i = 0; i < datepicker.pickers.length; i++) {
                const pick = datepicker.pickers[i];
                var localtarget = target;

                while (localtarget && localtarget !== pick.Target && localtarget.className != 'vanilla-datepicker') {
                    localtarget = localtarget.parentNode;
                }
                if (localtarget && localtarget === pick.Target) {
                    if(pick === datepicker.currentPick){
                        pick.hide();
                        datepicker.currentPick = null;
                    }else{
                        pick.show();
                        datepicker.currentPick = pick;
                    }
                }
                if (!localtarget) pick.hide();
            }
        }
    }
};


class DatePick {
    constructor(element, options) {
        this.Target = element;
        this.Options = options;

    }

    hide() {
        //var picker = document.querySelector('.vanilla-datepicker');
        if (this.Picker) this.Picker.remove();
    }




    show() {
        if (this.Target && this.Target.value) {
            var ts = Date.parse(this.Target.value.toLowerCase());
            var selected = new Date(ts);
            this.selected = { year: selected.getFullYear(), month: selected.getMonth(), day: selected.getDate() }
        }
        if (typeof this.current == typeof undefined) {
            if(!selected)
                selected = new Date();
            
            this.current = { year: selected.getFullYear(), month: selected.getMonth() }
        }
        this.cleanPicker();
        this.drawPicker();
    }

    cleanPicker () {
        if (this.Picker) this.Picker.remove();
    }

    drawPicker() {
        var pick = document.createElement('div');
        var position = this.getPosition(this.Target);
        pick.classList.add('vanilla-datepicker');
        pick.style.left = position.x + 'px';
        pick.style.top = (position.y + this.Target.offsetHeight) + 'px';
        pick.appendChild(this.drawNavigation());
        pick.appendChild(this.drawWeekHeader());
        var weeks = this.getWeeks();
        for (var i = 0;
            i < weeks.length;
            i++) {
            pick.appendChild(weeks[i]);
        }
        this.Picker = pick;
        document.body.appendChild(pick);
    }
    drawNavigation() {
        var nav = document.createElement('div');
        nav.classList.add('title-nav');

        if (this.Options.navigateYear) {
            var previousYear = document.createElement('div');
            previousYear.classList.add('year-navigate');
            previousYear.classList.add('previous');
            previousYear.innerHTML = '<<';
            var nextYear = document.createElement('div');
            nextYear.classList.add('year-navigate');
            nextYear.classList.add('next');
            nextYear.innerHTML = '>>';
        }
        var previousMonth = document.createElement('div');
        previousMonth.classList.add('month-navigate');
        previousMonth.classList.add('previous');
        previousMonth.innerHTML = '<';
        var currentMonth = document.createTextNode(this.Options.months.long[this.current.month] + ' ' + this.current.year);
        var nextMonth = document.createElement('div');
        nextMonth.classList.add('month-navigate');
        nextMonth.classList.add('next');
        nextMonth.innerHTML = '>';
        if (this.Options.navigateYear) nav.appendChild(previousYear);
        nav.appendChild(previousMonth);
        nav.appendChild(currentMonth);
        nav.appendChild(nextMonth);
        if (this.Options.navigateYear) nav.appendChild(nextYear);
        return nav;

    }

    drawWeekHeader() {
        var weekdays = this.Options.weekdays.short.slice(this.Options.firstDayOfWeek).concat(this.Options.weekdays.short.slice(0, this.Options.firstDayOfWeek));
        var weekHeader = document.createElement('div');
        weekHeader.classList.add('week-header');
        for (var i = 0;
            i < 7;
            i++) {
            var dayOfWeek = document.createElement('div');
            dayOfWeek.innerHTML = weekdays[i];
            weekHeader.appendChild(dayOfWeek);
        }
        return weekHeader;
    }

    getWeeks() {
        var weekdays = this.Options.weekdays.short.slice(this.Options.firstDayOfWeek).concat(this.Options.weekdays.short.slice(0, this.Options.firstDayOfWeek));
        var firstOfMonth = new Date(this.current.year, this.current.month, 1).getDay();
        firstOfMonth = firstOfMonth < this.Options.firstDayOfWeek ? 7 + (firstOfMonth - this.Options.firstDayOfWeek) : firstOfMonth - this.Options.firstDayOfWeek;
        var daysInPreviousMonth = new Date(this.current.year, this.current.month, 0).getDate();
        var daysInMonth = new Date(this.current.year, this.current.month + 1, 0).getDate();
        var days = [], weeks = [];
        for (var i = firstOfMonth - 1;
            i >= 0;
            i--) {
            var day = document.createElement('div');
            day.classList.add('no-select');
            day.innerHTML = daysInPreviousMonth - i;
            days.push(day);
        }
        for (var i = 0;
            i < daysInMonth;
            i++) {
            if (i && (firstOfMonth + i) % 7 === 0) {
                weeks.push(this.addWeek(days));
                days = [];
            }
            var day = document.createElement('div');
            day.classList.add('day');
            if (this.selected && this.selected.year == this.current.year && this.selected.month == this.current.month && this.selected.day == i + 1) {
                day.classList.add('selected');
            }
            day.innerHTML = i + 1;
            days.push(day);

        }
        if (days.length) {
            var len = days.length;
            for (var i = 0;
                i < 7 - len;
                i++) {
                var day = document.createElement('div');
                day.classList.add('no-select');
                day.innerHTML = i + 1;
                days.push(day);
            }
            weeks.push(this.addWeek(days));

        }
        return weeks;
    }

    addWeek(days) {
        var week = document.createElement('div');
        week.classList.add('week');
        for (var i = 0; i < days.length; i++) {
            week.appendChild(days[i]);
        }
        return week;
    }

    getPosition(element) {
        var xPosition = 0,
            yPosition = 0;

        while (element) {
            xPosition += (element.offsetLeft - element.scrollLeft + element.clientLeft);
            yPosition += (element.offsetTop - element.scrollTop + element.clientTop);
            element = element.offsetParent;
        }
        return {
            x: xPosition,
            y: yPosition
        };
    }

    getPreviousYear() {
        var current = new Date(this.current.year - 1, this.current.month);
        this.current = { year: current.getFullYear(), month: current.getMonth() };
        this.show();
    }
    getNextYear() {
        var current = new Date(this.current.year + 1, this.current.month);
        this.current = { year: current.getFullYear(), month: current.getMonth() };
        this.show();
    }
    getPreviousMonth() {
        var current = new Date(this.current.year, this.current.month - 1);
        this.current = { year: current.getFullYear(), month: current.getMonth() };
        this.show();
    }
    getNextMonth() {
        var current = new Date(this.current.year, this.current.month + 1);
        this.current = { year: current.getFullYear(), month: current.getMonth() };
        this.show();
    }
    setDate(day) {
        var dayOfWeek = new Date(this.current.year, this.current.month, day).getDay();
        var date = this.Options.outputFormat.replace('%a', this.Options.weekdays.short[dayOfWeek])
        .replace('%A', this.Options.weekdays.long[dayOfWeek])
        .replace('%d', ('0' + day).slice(-2)).replace('%e', day)
        .replace('%b', this.Options.months.short[this.current.month])
        .replace('%B', this.Options.months.long[this.current.month])
        .replace('%m', ('0' + (this.current.month + 1)).slice(-2))
        .replace('%w', dayOfWeek).replace('%Y', this.current.year);
        this.Target.value = date;
    }
}
datepicker.defaults = { firstDayOfWeek: 0, months: { short: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], long: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] }, navigateYear: true, outputFormat: '%Y-%m-%d', weekdays: { short: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], long: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] } };
var extend = function (out) {
    out = out || {};
    for (var i = 1;
        i < arguments.length;
        i++) {
        if (!arguments[i])
            continue;
        for (var key in arguments[i]) {
            if (arguments[i].hasOwnProperty(key))
                out[key] = arguments[i][key];

        }
    }
    return out;

}